module hist_equ_top #(
parameter WIDTH  = 256,
parameter HEIGHT = 200
)(
    input        clk,
	input        rst_n,
    input        proc_en,//算法打开，高有效
    input        sink_sop,
    input        sink_valid,
    input  [11:0] sink_data,
    input        sink_eop,
    output       sink_ready,
    output       source_sop,
    output       source_valid,
    output [11:0] source_data,
    output       source_eop,
    input        source_ready
);
//统计模块操作统计ram的接口
wire        static_ram_read_w,static_ram_write_w;
wire [15:0] static_ram_data_w,static_ram_q_w;
wire [11:0]  static_ram_wraddress_w,static_ram_rdaddress_w;
//累积模块操作统计ram的接口
wire        static_ram_read_w1,static_ram_write_w1;
wire [15:0] static_ram_data_w1,static_ram_q_w1;
wire [11:0]  static_ram_wraddress_w1,static_ram_rdaddress_w1;
//统计ram接口
wire        static_ram_read,static_ram_write;
wire [15:0] static_ram_data,static_ram_q;
wire [11:0]  static_ram_wraddress,static_ram_rdaddress;

wire        static_done_w,cumulate_done_w;
wire        static_done_w1;//static_done_w延迟一个时钟
wire        ready_en_w;
//fifo清空信号
wire fifo_aclr_w;
//scfifo接口
wire fifo_almost_full_w;
wire fifo_empty_w,fifo_rd_w;
wire [11:0] fifo_q_w;
wire [11:0] fifo_data_w;
//remap ram接口
wire [11:0] remap_ram_data_w,remap_ram_q_w;
wire [11:0] remap_ram_wraddress_w,remap_ram_rdaddress_w;
wire       remap_ram_write_w,remap_ram_read_w;
wire       remap_ram_q_valid_w;//remap_ram_q有效标志
//sink_data 延迟2个时钟
wire [11:0] sink_data_w;
//assign fifo_aclr_w = 1'b0;//sink_valid && sink_sop;
assign sink_ready = !(sink_valid && sink_eop) && !fifo_almost_full_w && ready_en_w;
assign fifo_data_w = proc_en?remap_ram_q_w:sink_data_w;
//统计模块
hist_equ_static u_hist_equ_static_0 
(
	.clk(clk),
	.rst_n(rst_n),
	.sink_sop(sink_sop),
	.sink_eop(sink_eop),
	.sink_valid(sink_valid),
	.sink_data(sink_data),
	.static_done(static_done_w),//标志一帧统计结束，持续一个时钟的高电平
	.static_ram_data(static_ram_data_w),//19位以保证可以表示640*480
	.static_ram_write(static_ram_write_w),
	.static_ram_wraddress(static_ram_wraddress_w),//256种灰度
	.static_ram_read(static_ram_read_w),
	.static_ram_rdaddress(static_ram_rdaddress_w),
	.static_ram_q(static_ram_q_w)
	);	
hist_equ_static_ram u_hist_equ_static_ram_0 (
	.clock(clk),
	.data(static_ram_data),
	.rdaddress(static_ram_rdaddress),
	.rden(static_ram_read),
	.wraddress(static_ram_wraddress),
	.wren(static_ram_write),
	.q(static_ram_q)
	);	
//累积模块（累积模块内部做了remap）
hist_equ_cumulate #(
    .WIDTH(WIDTH),
	 .HEIGHT(HEIGHT)
)
u_hist_equ_cumulate_0
(
    .clk(clk),
    .rst_n(rst_n),
    .static_done(static_done_w),//统计完成标志
    .cumulate_done(cumulate_done_w),//累计完成标志
    .static_ram_data(static_ram_data_w1),
    .static_ram_write(static_ram_write_w1),
    .static_ram_wraddress(static_ram_wraddress_w1),
    .static_ram_read(static_ram_read_w1),
    .static_ram_rdaddress(static_ram_rdaddress_w1),
    .static_ram_q(static_ram_q_w1),
    .remap_data(remap_ram_data_w),
    .remap_wraddress(remap_ram_wraddress_w),
    .remap_write(remap_ram_write_w)
);
//视频流控制模块
hist_equ_st_ctr u_hist_equ_st_ctr_0
(
	.clk(clk),
	.rst_n(rst_n),
	.static_done(static_done_w),//直方图统计完成标志，高有效，一般持续一个clk周期
	.cumulate_done(cumulate_done_w),//直方图累计和RAM清空完成标志，高有效，一般持续一个clk周期
	.ready_en(ready_en_w)
	);
//对延迟一个时钟
hist_equ_shift_regs#(
    .DWIDTH(1),//数据位宽
    .DELAY_DUTY(1)//延迟的时钟周期数，最小是1
)u_hist_equ_shift_regs_1
(
    .clk(clk),
    .rst_n(rst_n),
    .idata(static_done_w),
    .odata(static_done_w1)
);
//统计RAM读写的仲裁模块
hist_equ_ram_bus_arbit
#(
    .DWIDTH(16),//RAM数据位宽
    .AWIDTH(12) //RAM地址位宽
)
u_hist_equ_ram_bus_arbit_0
(
	.clk(clk),
	.rst_n(rst_n),
	.state(!(ready_en_w || static_done_w1)),
    
    .static_data(static_ram_data_w),
    .static_write(static_ram_write_w),
    .static_wraddress(static_ram_wraddress_w),
    .static_read(static_ram_read_w),
    .static_rdaddress(static_ram_rdaddress_w),
    .static_q(static_ram_q_w),
    
    .cumulate_data(static_ram_data_w1),
    .cumulate_write(static_ram_write_w1),
    .cumulate_wraddress(static_ram_wraddress_w1),
    .cumulate_read(static_ram_read_w1),
    .cumulate_rdaddress(static_ram_rdaddress_w1),
    .cumulate_q(static_ram_q_w1),
    
    .ram_data(static_ram_data),
    .ram_write(static_ram_write),
    .ram_wraddress(static_ram_wraddress),
    .ram_read(static_ram_read),
    .ram_rdaddress(static_ram_rdaddress),
    .ram_q(static_ram_q)
	);
//remap ram
hist_equ_remap_ram u_hist_equ_remap_ram_0 (
	.clock(clk),
	.data(remap_ram_data_w),
	.rdaddress(sink_data),
	.rden(sink_valid),
	.wraddress(remap_ram_wraddress_w),
	.wren(remap_ram_write_w),
	.q(remap_ram_q_w)
	);
//产生remap_ram_q_valid_w
hist_equ_shift_regs#(
    .DWIDTH(1),//数据位宽
    .DELAY_DUTY(2)//延迟的时钟周期数，最小是1
)u_hist_equ_shift_regs_0
(
    .clk(clk),
    .rst_n(rst_n),
    .idata(sink_valid),
    .odata(remap_ram_q_valid_w)
);
//对sink_data延迟2个时钟
hist_equ_shift_regs#(
    .DWIDTH(12),//数据位宽
    .DELAY_DUTY(2)//延迟的时钟周期数，最小是1
)u_hist_equ_shift_regs_3
(
    .clk(clk),
    .rst_n(rst_n),
    .idata(sink_data),
    .odata(sink_data_w)
);
//产生aclr信号
hist_equ_shift_regs#(
    .DWIDTH(1),//数据位宽
    .DELAY_DUTY(1)//延迟的时钟周期数，最小是1
)u_hist_equ_shift_regs_2
(
    .clk(clk),
    .rst_n(rst_n),
    .idata(sink_valid && sink_sop),
    .odata(fifo_aclr_w)
);
//scfifo
hist_equ_scfifo u_hist_equ_scfifo_0 
(
	.aclr(fifo_aclr_w),
	.clock(clk),
	.data(fifo_data_w),
	.rdreq(fifo_rd_w),
	.wrreq(remap_ram_q_valid_w),
	.almost_full(fifo_almost_full_w),
	.empty(fifo_empty_w),
	.q(fifo_q_w)
);
//fifo2st
hist_equ_fifo2st #(
     .DWIDTH(12),
     .TOTAL_PIXELS(WIDTH*HEIGHT)
)
u_hist_equ_fifo2st_0
(
     .clk(clk),              //本模块将FIFO数据转化成非标Avalon-ST视频流，即不带控制包头，并且无视频数据包头，sop对应一帧的第一个有效数据,eop对应一帧的最后一个有效数据
     .rst_n(rst_n),
     .fifo_aclr(fifo_aclr_w),        //外部模块需要根据视频流特征生成扇出FIFO的异步aclr信号
     .fifo_empty(fifo_empty_w),       //FIFO空标志信号
     .fifo_q(fifo_q_w),
     .fifo_rd(fifo_rd_w),
     .source_sop(source_sop),
     .source_valid(source_valid),
     .source_data(source_data),
     .source_eop(source_eop),
     .source_ready(source_ready)
               );
endmodule 